//
// Created by jack on 2021/2/2.
//

#ifndef WEILACSDK_WEILAPB_INTERNAL_H
#define WEILACSDK_WEILAPB_INTERNAL_H

#include "weilapb_defines.h"

#ifdef WIN32
#    define WL_LOG pWeilaCtx->pbFunHook.weilaLog
#else
#    define WL_LOG(...)                                                                                                \
        do {                                                                                                           \
            if (pWeilaCtx->pbFunHook.weilaLog) {                                                                       \
                pWeilaCtx->pbFunHook.weilaLog(__VA_ARGS__);                                                            \
            }                                                                                                          \
        } while (0)
#endif

typedef struct _MEM_INFO_DATA {
    PB_CHAR*  pFilename;
    PB_UINT32 lineNumber;
    PB_UINT32 memSize;
    PB_UINT32 valid;
    void*     pPtr;
} PBMemInfo;

typedef struct _WEILA_CTX {
    PBFunHook pbFunHook;
    PB_UINT8* pRecvBuffer;
    PB_UINT32 recvSize;
    PB_UINT32 bufferSize;
    PB_UINT32 packageLen;  //超大数据包长度
    PB_UINT32 leftLen;  //超大数据包剩余长度(当packageLen超过缓存限制时有效leftLen为0丢弃数据)
    PB_EVENT_LISTENER listener;
    PB_UINT32         seq;

    // 用以ptt语音
    PB_UINT64 curPttSessionId;
    PB_UINT32 curPttSenderId;
    PB_UINT32 curPttMsgId;
    PB_UINT16 curPttSessionType;
    PB_UINT16 curPttMarker;
    PB_UINT16 curPttSeq;
    PB_UINT16 curPttPackageSeq;
    // end

    // SDK和设备相关信息
    PB_CHAR appId[MAX_PHONE_NUM_LEN];
    PB_CHAR appKey[MAX_SHORT_STRING_LEN];
    PB_CHAR deviceSpecial[MAX_NORMAL_STRING_LEN];
    PB_CHAR deviceInfo[MAX_URL_STRING_LEN];
    // end

#ifdef DEBUG_MEM
    PBMemInfo memInfoLink[1024];
    PBMemInfo maxMemInfo;
#endif
} WeilaCtx;

#define WEILA_MESSAGE_HEADER_LENGTH 16
typedef struct _WEILA_MSG_HEADER {
    PB_UINT32 length;
    PB_UINT16 version;
    PB_UINT16 flag;
    PB_UINT16 serviceId;
    PB_UINT16 commandId;
    PB_UINT16 seq;
    PB_UINT16 reserved;
} WeilaMsgHeader;

typedef struct _SERVICE_COMMAND_MESSAGE_MAP {
    PB_UINT32 id;
    PB_UINT32 message;
} ServiceCommandMessageMap;

#define ID(serviceId, commandId) (((PB_UINT32)serviceId) << 16 | commandId)

#define PB_ALLOC(size) weilapb_alloc(size, __FILE__, __LINE__)

#define PB_FREE(ptr) weilapb_free(ptr, __FILE__, __LINE__)

extern WeilaCtx* pWeilaCtx;
extern void*     weilapb_alloc(PB_UINT32 size, PB_CHAR* filename, PB_INT32 line);
extern void      weilapb_free(void* ptr, char* filename, int line);
extern void      weilapb_encodeWeilaMsgHeader(WeilaMsgHeader* pWeilaMsgHeader, PB_UINT8* pBuffer);
extern PB_UINT32 weilapb_getMessageByCommandId(PB_UINT16 serviceId, PB_UINT16 commandId);
#ifdef DEBUG_MEM
extern void weilapb_printMemInfo();
#endif

#endif  // WEILACSDK_WEILAPB_INTERNAL_H
